package com.weitu.securitycheck.controller;

import com.weitu.accessory.service.AccessoryUtilService;
import com.weitu.base.annotaion.SystemLog;
import com.weitu.base.controller.BaseController;
import com.weitu.paging.DataGridPagination;
import com.weitu.permission.dataAuthority.service.DataAuthorityService;
import com.weitu.permission.department.service.DepartmentService;
import com.weitu.permission.user.entity.User;
import com.weitu.permission.user.service.UserService;
import com.weitu.plugin.PageView;
import com.weitu.securitycheck.entity.CheckInfo;
import com.weitu.securitycheck.entity.CheckInfoCriteria;
import com.weitu.securitycheck.entity.CheckProblem;
import com.weitu.securitycheck.entity.CheckProblemCriteria;
import com.weitu.securitycheck.service.CheckInfoService;
import com.weitu.securitycheck.service.CheckProblemService;
import com.weitu.util.AjaxResult;
import com.weitu.util.DateTimeUtil;
import com.weitu.util.IDGenerator;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static com.weitu.util.AjaxResult.fail;
import static com.weitu.util.AjaxResult.success;

/**
 * @author LiMeng 2017/5/13
 */
@Controller
@RequestMapping(value = "securityCheck/checkInfo")
public class CheckInfoController extends BaseController {
    private static final String MODULE_BATH_PATH = BASE_JSP_PATH + "securityCheck/checkInfo";
    private final CheckInfoService checkInfoService;
    private final DepartmentService departmentService;
    private final UserService userService;
    private final CheckProblemService checkProblemService;
    private final DataAuthorityService dataAuthorityService;
    private final AccessoryUtilService accessoryUtilService;

    @Autowired
    public CheckInfoController(CheckInfoService checkInfoService
            , DepartmentService departmentService
            , UserService userService
            , CheckProblemService checkProblemService
            , DataAuthorityService dataAuthorityService
            , AccessoryUtilService accessoryUtilService) {
        this.checkInfoService = checkInfoService;
        this.departmentService = departmentService;
        this.userService = userService;
        this.checkProblemService = checkProblemService;
        this.dataAuthorityService = dataAuthorityService;
        this.accessoryUtilService = accessoryUtilService;
    }

    @RequestMapping(value = "list", method = RequestMethod.GET)
    public String list() {
        return MODULE_BATH_PATH + "/list";
    }

    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public String add(Model model) {
        model.addAttribute("loginUserId", getSessionUser().getId());
        model.addAttribute("loginDeptId", getSessionUser().getDepartment().getId());
        return MODULE_BATH_PATH + "/add";
    }

    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public String edit(Model model, String id) {
        model.addAttribute("loginUserId", getSessionUser().getId());
        putModelAttributes(model, id);
        return MODULE_BATH_PATH + "/edit";
    }

    @RequestMapping(value = "/view", method = RequestMethod.GET)
    public String view(Model model, String id) {
        model.addAttribute("loginUserId", getSessionUser().getId());
        putModelAttributes(model, id);
        return MODULE_BATH_PATH + "/view";
    }

    @ResponseBody
    @RequestMapping(value = "list", method = RequestMethod.POST)
    public Object listAjax(HttpServletRequest request, String sort) throws Exception {
        CheckInfoCriteria criteria = new CheckInfoCriteria();
        CheckInfoCriteria.Criteria cr = criteria.createCriteria()
                .andDelStateEqualTo(0);
        putSearchCriteria(cr);

        int count = checkInfoService.countByCriteria(criteria);

        DataGridPagination dataGridPagination = DataGridPagination.getInstance(request, count);//获取分页对象
        PageView pageView = dataGridPagination.getPageView();//生成pageView分页对象
        //未传sort参数是采用添加时间排序
        if (StringUtils.isEmpty(sort)) {
            pageView.setSortColumn("addTime");
        } else {
            criteria.setOrderByClause(pageView.getSortColumn() + " " + pageView.getOrderType());
        }
        criteria.setPageView(pageView);

        List<CheckInfo> checkInfoList = checkInfoService.selectByCriteria(criteria);
        for (CheckInfo checkInfo : checkInfoList) {
            setCheckDeptNames(checkInfo);
            setCheckUserNames(checkInfo);
        }

        return dataGridPagination.flushDataGridData(checkInfoList);
    }

    @SystemLog(module = "检查信息", methods = "新增检查信息")
    @ResponseBody
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public AjaxResult addAjax(CheckInfo checkInfo) throws Exception {
        String id = IDGenerator.getId();
        checkInfo.setId(id);
        checkInfo.setAddUserId(getSessionUser().getId());
        checkInfo.setAddDeptId(getSessionUser().getDepartment().getId());
        checkInfo.setAddTime(DateTimeUtil.formatterDateTime());

        if (checkInfoService.saveAccessoryAndInsert(checkInfo)) {
            return success("保存成功！", checkInfo);
        }
        return fail("保存失败！");
    }

    @SystemLog(module = "检查信息", methods = "修改检查信息")
    @ResponseBody
    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    public AjaxResult editAjax(CheckInfo checkInfo) throws Exception {
        checkInfo.setUpdateUserId(getSessionUser().getId());
        checkInfo.setUpdateDeptId(getSessionUser().getDepartment().getId());
        checkInfo.setUpdateTime(DateTimeUtil.formatterDateTime());
        CheckDate checkDate = new CheckDate(checkInfo.getId()).invoke();
        checkInfo.setCheckStartDate(checkDate.getStartDate());
        checkInfo.setCheckEndDate(checkDate.getEndDate());
        if (checkInfoService.saveAccessoryAndUpdate(checkInfo)) {
            return success("保存成功！", checkInfo);
        }
        return fail("保存失败！");
    }

    @SystemLog(module = "检查信息", methods = "删除检查信息")
    @ResponseBody
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    public AjaxResult deleteAjax(String id) throws Exception {
        if (checkInfoService.deleteByPrimaryKey(id) > 0) {
            return success("删除成功！");
        } else {
            return fail("删除失败！");
        }
    }

    @SystemLog(module = "检查信息", methods = "更新检查信息的检查开始和结束日期")
    @ResponseBody
    @RequestMapping(value = "/updateDate", method = RequestMethod.POST)
    public AjaxResult updateDateAjax(@RequestParam("id") String id) throws Exception {
        CheckDate checkDate = new CheckDate(id).invoke();
        String startDate = checkDate.getStartDate();
        String endDate = checkDate.getEndDate();
        CheckInfo checkInfo = new CheckInfo();
        checkInfo.setId(id);
        checkInfo.setCheckStartDate(startDate);
        checkInfo.setCheckEndDate(endDate);
        checkInfo.setUpdateUserId(getSessionUser().getId());
        checkInfo.setUpdateDeptId(getSessionUser().getDepartment().getId());
        checkInfo.setUpdateTime(DateTimeUtil.formatterDateTime());
        if (checkInfoService.updateByPrimaryKeySelective(checkInfo) > 0) {
            return success("保存成功！");
        }
        return fail("保存失败！");
    }

    /**
     * 根据检查人id逗号分隔字符串设置相关名称的值
     *
     * @param checkInfo 实体
     */
    private void setCheckUserNames(CheckInfo checkInfo) {
        if (StringUtils.isNotEmpty(checkInfo.getCheckUserIds())) {
            String[] idArray = checkInfo.getCheckUserIds().split(",");
            List<User> users = userService.selectUsersByIds(idArray);
            if (!users.isEmpty()) {
                StringBuilder sb = new StringBuilder();
                for (User user : users) {
                    String userName = user.getRealName();
                    sb.append(",").append(userName);
                }
                checkInfo.setCheckUserNames(sb.toString().substring(1));
            }
        }
    }

    /**
     * 根据检查部门id逗号分隔字符串设置相关名称的值
     *
     * @param checkInfo 实体
     */
    private void setCheckDeptNames(CheckInfo checkInfo) {
        if (StringUtils.isNotEmpty(checkInfo.getCheckDeptIds())) {
            String[] idArray = checkInfo.getCheckDeptIds().split(",");
            List<String> ids = Arrays.asList(idArray);
            String namesStr = StringUtils.join(departmentService.selectNamesByIds(ids), ',');
            checkInfo.setCheckDeptNames(namesStr);
        }
    }

    /**
     * 添加查询条件
     *
     * @param criteria 条件
     */
    private void putSearchCriteria(CheckInfoCriteria.Criteria criteria) {
        if (StringUtils.isNotEmpty(getPara("name"))) {
            criteria.andNameLike("%" + getPara("name") + "%");
        }
        if (StringUtils.isNotEmpty(getPara("checkLevelId"))) {
            criteria.andCheckLevelIdEqualTo(getPara("checkLevelId"));
        }
        if (StringUtils.isNotEmpty(getPara("checkTypeId"))) {
            criteria.andCheckTypeIdEqualTo(getPara("checkTypeId"));
        }
        if (StringUtils.isNotEmpty(getPara("checkDeptId"))) {
            criteria.andCheckDeptIdsLike("%" + getPara("checkDeptId") + "%");
        }
        if (StringUtils.isNotEmpty(getPara("checkUserId"))) {
            criteria.andCheckUserIdsLike("%" + getPara("checkUserId") + "%");
        }
        if (StringUtils.isNotEmpty(getPara("checkStartDate"))) {
            criteria.andCheckStartDateEqualTo(getPara("checkStartDate"));
        }
        if (StringUtils.isNotEmpty(getPara("checkEndDate"))) {
            criteria.andCheckEndDateEqualTo(getPara("checkEndDate"));
        }
        if (StringUtils.isNotEmpty(getPara("addTimeMin"))) {
            criteria.andAddTimeGreaterThanOrEqualTo(getPara("addTimeMin"));
        }
        if (StringUtils.isNotEmpty(getPara("addTimeMax"))) {
            criteria.andAddTimeLessThanOrEqualTo(getPara("addTimeMax"));
        }
        if (StringUtils.isNotEmpty(getPara("addUserId"))) {
            criteria.andAddUserIdEqualTo(getPara("addUserId"));
        }
        if (StringUtils.isNotEmpty(getPara("addDeptId"))) {
            criteria.andAddDeptIdEqualTo(getPara("addDeptId"));
        }
        List<String> deptIds = dataAuthorityService.selectDataDeptIdByUserIdAndDeptId(getSessionUser().getId()
                , getSessionUser().getDepartment().getId());
        if (!deptIds.isEmpty()) {
            criteria.andAddDeptIdIn(deptIds);
        }
    }

    /**
     * 向页面实体添加属性
     *
     * @param model 页面实体
     * @param id    主键id
     */
    private void putModelAttributes(Model model, String id) {
        CheckInfo checkInfo = checkInfoService.selectByPrimaryKey(id);
        setCheckUserNames(checkInfo);
        model.addAttribute("accessoryList", accessoryUtilService.queryAccessoryByBusinessId(id));
        model.addAttribute("checkInfo", checkInfo);
    }

    private class CheckDate {
        private String checkInfoId;
        private String startDate;
        private String endDate;

        public CheckDate(String checkInfoId) {
            this.checkInfoId = checkInfoId;
        }

        public String getStartDate() {
            return startDate;
        }

        public String getEndDate() {
            return endDate;
        }

        public CheckDate invoke() {
            CheckProblemCriteria example = new CheckProblemCriteria();
            example.createCriteria().andDelStateEqualTo(0).andCheckInfoIdEqualTo(checkInfoId);
            List<CheckProblem> checkProblems = checkProblemService.selectByCriteria(example);
            if (checkProblems.size() > 0) {
                List<String> dateList = new ArrayList<String>();
                for (CheckProblem problem : checkProblems) {
                    String checkDate = problem.getCheckDate();
                    if (checkDate != null) {
                        dateList.add(checkDate);
                    }
                }
                startDate = Collections.min(dateList);
                endDate = Collections.max(dateList);
            }
            return this;
        }
    }
}
